#ifndef _MY_SERVER_
#define _MY_SERVER_
#include "data.hpp"
#include "httplib.h"
#include <jsoncpp/json/value.h>
const std::string kRoot = "./www";
const std::string kVideoRoot = "/video/";
const std::string kImageRoot = "/image/";
TableVideo *table_video = nullptr;
class Server {
private:
  int port_;
  httplib::Server server_;

private:
  static void Insert(const httplib::Request &req, httplib::Response &res) {
    if (req.has_file("name") == false || req.has_file("info") == false ||
        req.has_file("video") == false || req.has_file("image") == false) {
      ResponseUtil::FailWithMessage("上传的数据信息错误", 400, res);
      return;
    }
    httplib::MultipartFormData name = req.get_file_value("name");
    httplib::MultipartFormData info = req.get_file_value("info");
    httplib::MultipartFormData video = req.get_file_value("video");
    httplib::MultipartFormData image = req.get_file_value("image");
    std::string video_name = name.content;
    std::string vidoe_info = info.content;
    std::string video_path = kRoot + kVideoRoot + video_name + video.filename;
    std::string image_path = kRoot + kImageRoot + video_name + image.filename;

    if (FileUtil(video_path).SetContent(video.content) == false) {
      ResponseUtil::FailWithMessage("视频文件存储失败", 500, res);
      return;
    }
    if (FileUtil(image_path).SetContent(image.content) == false) {
      ResponseUtil::FailWithMessage("图片文件存储失败", 500, res);
      return;
    }

    Json::Value video_json;
    video_json["name"] = video_name;
    video_json["info"] = vidoe_info;
    video_json["video"] = kVideoRoot + video_name + video.filename;
    video_json["image"] = kImageRoot + video_name + image.filename;
    if (table_video->Insert(video_json) == false) {
      ResponseUtil::FailWithMessage("数据库新增数据失败", 500, res);
      return;
    }
    res.set_redirect("/index.html", 303);
    return;
  }
  static void Update(const httplib::Request &req, httplib::Response &res) {
    int video_id = std::stoi(req.matches[1].str());

    Json::Value video;
    if (JsonUtil::UnSerialize(req.body, &video) == false) {
      ResponseUtil::FailWithMessage("数据格式错误", 400, res);
      return;
    }
    if (table_video->Update(video_id, video) == false) {
      ResponseUtil::FailWithMessage("数据库更新数据失败", 500, res);
      return;
    }
    return;
  }
  static void Delete(const httplib::Request &req, httplib::Response &res) {
    int video_id = std::stoi(req.matches[1].str());
    Json::Value video;
    if (table_video->SelectOne(video_id, &video) == false) {
      ResponseUtil::FailWithMessage("不存在数据信息", 500, res);
      return;
    }
    std::string root = kRoot;
    std::string video_path = root + video["video"].asString();
    std::string image_path = root + video["image"].asString();
    if (remove(video_path.c_str()) != 0) {
      ResponseUtil::FailWithMessage("视频文件删除失败", 500, res);
      return;
    }
    if (remove(image_path.c_str()) != 0) {
      ResponseUtil::FailWithMessage("图片文件删除失败", 500, res);
      return;
    }

    if (table_video->Delete(video_id) != true) {
      ResponseUtil::FailWithMessage("数据库删除数据失败", 500, res);
      return;
    }
    return;
  }
  static void SelectAll(const httplib::Request &req, httplib::Response &res) {
    bool select_all = true;
    std::string search_key;
    if (req.has_param("search")) {
      select_all = false;
      search_key = req.get_param_value("search");
    }
    Json::Value videos;
    if (select_all == true) {
      if (table_video->SelectAll(&videos) == false) {
        ResponseUtil::FailWithMessage("数据库查询数据失败", 500, res);
        return;
      }
    } else {
      if (table_video->SelectLike(search_key, &videos) == false) {
        ResponseUtil::FailWithMessage("数据库查询数据失败", 500, res);
        return;
      }
    }
    JsonUtil::Serialize(videos, &res.body);
    res.set_header("Content-Type", "application/json");
    return;
  }
  static void SelectOne(const httplib::Request &req, httplib::Response &res) {
    int video_id = std::stoi(req.matches[1].str());
    Json::Value video;
    if (table_video->SelectOne(video_id, &video) == false) {
      ResponseUtil::FailWithMessage("不存在数据信息", 500, res);
      return;
    }
    JsonUtil::Serialize(video, &res.body);
    res.set_header("Content-Type", "application/json");
  }

  static void SelectLike(const httplib::Request &req, httplib::Response &res) {
    std::string key = req.matches[1];
    if (key.empty()) {
      Server::SelectAll(req, res);
      return;
    }
    Json::Value videos;
    if (table_video->SelectLike(key, &videos) == false) {
      ResponseUtil::FailWithMessage("不存在数据信息", 500, res);
      return;
    }
    JsonUtil::Serialize(videos, &res.body);
    res.set_header("Content-Type", "application/json");
  }

public:
  Server(int port) : port_(port) {}
  bool Run() {
    table_video = new TableVideo();
    std::string video_real_path = kRoot + kVideoRoot;
    std::string image_real_path = kRoot + kImageRoot;
    FileUtil(kRoot).CreateDirectory();
    FileUtil(video_real_path).CreateDirectory();
    FileUtil(image_real_path).CreateDirectory();
    server_.set_mount_point("/", kRoot);
    server_.Post("/video", Insert);
    server_.Delete("/video/(\\d+)", Delete);
    server_.Put("/video/(\\d+)", Update);
    server_.Get("/video", SelectAll);
    server_.Get("/video/(\\d+)", SelectOne);
    server_.Get("/video?key=", SelectLike);
    std::cout << "开始监听端口" << std::endl;
    if (server_.listen("0.0.0.0", port_) == false) {
      std::cerr << "listen error" << std::endl;
    }
    return true;
  }
};

#endif
